package com.lin.filegraph.utils.cluster;

import com.lin.filegraph.utils.compdg.ComponentGraph;
import com.lin.filegraph.utils.compdg.ComponentNode;

import java.util.ArrayList;
import java.util.List;

/**
 * @description:
 * @author: linhuaixu
 * @time: 2023/5/18 16:05
 */

public class ClusterPreJudge {

    public static boolean enableCluster(ComponentNode node1, ComponentNode node2, ComponentGraph graph) {
//		Timer timer = new Timer();
        if ((!graph.getAllComponents().contains(node1)) && (!graph.getAllComponents().contains(node2))) {
            return false;
        }
        List<ComponentNode> visitedNodes = new ArrayList<>();
        if (findPredictedLoop(node1, node2, node1, graph, 0, visitedNodes)) {
//			timer.endTimer("enableCluster false");
            return false;
        }
        visitedNodes = new ArrayList<>();
        if (findPredictedLoop(node2, node1, node2, graph, 0, visitedNodes)) {
//			timer.endTimer("enableCluster false");
            return false;
        }
//		timer.endTimer("enableCluster true");
        return true;
    }

    private static boolean findPredictedLoop(ComponentNode startNode, ComponentNode endNode,
                                             ComponentNode initStartNode, ComponentGraph graph, int level, List<ComponentNode> visitedNodes) {
        if (level > 5) {
            return false;
        }
        if ((!graph.getAllComponents().contains(startNode)) || (!graph.getAllComponents().contains(endNode))) {
            return false;
        }
        visitedNodes.add(startNode);
        // if(level == 0) {
        // if(graph.getPostComponents(startNode).contains(endNode) &&
        // graph.getPostComponents(endNode).contains(startNode)) {
        // return false;
        // }
        // }
        if (startNode.equals(endNode)) {
            return true;
        }
        boolean hasPredictedLoop = false;
        for (ComponentNode nextNode : graph.getPostComponents(startNode)) {
            if (startNode.equals(initStartNode) && nextNode.equals(endNode)) {
                continue;
            }
            if(visitedNodes.contains(nextNode)) {
                continue;
            }
            if (findPredictedLoop(nextNode, endNode, initStartNode, graph, level + 1, visitedNodes)) {
                hasPredictedLoop = true;
                break;
            }
        }
        // if(initStartNode.getStrComponentName().equals("src/test/java/com/github/searls/jasmine/server")
        // &&
        // endNode.getStrComponentName().equals("src/test/java/org/eclipse/jetty/server"))
        // {
        // System.out.println("aaa" + startNode);
        // System.out.println(graph.getPostComponents(startNode));
        // System.out.println(hasPredictedLoop);
        // }
        return hasPredictedLoop;
    }
}

